﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BusinessBingo.CommandHandlers.Interfaces;
using BusinessBingo.CommandHandlers.Results;
using BusinessBingo.Commands;
using BusinessBingo.Model;
using BusinessBingo.Queries;
using BusinessBingo.QueryHandlers.Interfaces;
using BusinessBingo.QueryHandlers.Results;
using BusinessBingo.Web.Bindings;
using BusinessBingo.Web.Controllers.Base;
using BusinessBingo.Web.Infrastructure.InfoStores.Interfaces;
using BusinessBingo.Web.Infrastructure.InfoStores.Keys;
using BusinessBingo.Web.Models.PostModels;
using BusinessBingo.Web.Models.ViewModels;

namespace BusinessBingo.Web.Controllers
{
    public class GameController : Controller
    {
        private IStartNewGameCommandHandler _startNewGameCommandHandler;
        private ICurrentLanguageStore _currentLanguageStore;
        private ICookieRepository _cookieRepository;
        private HttpRequestBase _httpRequestBase;
        private ICheckFirstWordInBingoSetAsAnonymousCommandHandler _checkFirstWordInBingoSetAsAnonoymousCommandHandler;

        private int _bingoSetSize = 4;
        private ICheckWordCommandHandler _checkWordCommandHandler;

        public GameController(
            IStartNewGameCommandHandler startNewGameCommandHandler,
            ICurrentLanguageStore currentLanguageStore,
            ICookieRepository cookieRepository,
            ICheckFirstWordInBingoSetAsAnonymousCommandHandler checkFirstWordInBingoSetAsAnonoymousCommandHandler,
            ICheckWordCommandHandler checkWordCommandHandler,
            HttpRequestBase httpRequestBase)
        {
            this._startNewGameCommandHandler = startNewGameCommandHandler;
            this._checkFirstWordInBingoSetAsAnonoymousCommandHandler = checkFirstWordInBingoSetAsAnonoymousCommandHandler;
            this._checkWordCommandHandler = checkWordCommandHandler;
            
            this._currentLanguageStore = currentLanguageStore;
            this._cookieRepository = cookieRepository;
            this._httpRequestBase = httpRequestBase;
        }

        public ActionResult New(CurrentUserData cookieData, bool exitOldGames)
        {
            ActionResult redirectTo = Redirect(this._httpRequestBase.UrlReferrer.AbsoluteUri);

            if (cookieData == default(CurrentUserData))
                return redirectTo;

            LanguageKey language = this._currentLanguageStore.GetPreferredLanguage();

            StartNewGameCommand startNewGameCommand = new StartNewGameCommand(cookieData.GameId, this._bingoSetSize,
                                                                              language);
            this._startNewGameCommandHandler.IsMaster = true;
            StartNewGameCommandHandlerResult startNewGameCommandHandlerResult =
                this._startNewGameCommandHandler.Execute(startNewGameCommand);

            if (startNewGameCommandHandlerResult.Succeeded == false)
                return redirectTo;

            this._cookieRepository.UpdateElement(CookieKeys.GameId, startNewGameCommandHandlerResult.Game.Id.ToString());

            return RedirectToAction("Play","Group",
                                    new
                                    {
                                        groupUrl = startNewGameCommandHandlerResult.GroupUrl,
                                        gameNumber = startNewGameCommandHandlerResult.Game.Number
                                    });

            return redirectTo;
        }

        [HttpPost]
        public ActionResult CheckWord(CurrentUserData cookieData, BingoSetCheckWordPostModel model)
        {
            if (cookieData == default(CurrentUserData))
            {
                LanguageKey language = this._currentLanguageStore.GetPreferredLanguage();
                model.BingoSet.Language = language;

                CheckFirstWordInBingoSetAsAnonymousCommand checkFirstWordInBingoSetAsAnonymousCommand =
                    new CheckFirstWordInBingoSetAsAnonymousCommand(model.BingoSet, model.ClickedWordId);

                this._checkFirstWordInBingoSetAsAnonoymousCommandHandler.IsMaster = true;
                CheckFirstWordInBingoSetAsAnonymousCommandHandlerResult
                    checkFirstPositionInBingoSetAsAnonoymousCommandResult =
                        this._checkFirstWordInBingoSetAsAnonoymousCommandHandler.Execute(
                            checkFirstWordInBingoSetAsAnonymousCommand);

                this._cookieRepository.AddElement(CookieKeys.UserId,
                                                  checkFirstPositionInBingoSetAsAnonoymousCommandResult.UserId.ToString());
                this._cookieRepository.AddElement(CookieKeys.GameId,
                                                  checkFirstPositionInBingoSetAsAnonoymousCommandResult.GameId.ToString());
            }
            else
            {
                this._checkWordCommandHandler.IsMaster = true;

                CheckWordCommand checkWordCommand = new CheckWordCommand(cookieData.UserId, cookieData.GameId, model.ClickedWordId);
                this._checkWordCommandHandler.Execute(checkWordCommand);
            }

            return Redirect(this._httpRequestBase.UrlReferrer.AbsoluteUri);
        }
    }
}
